package gorm2

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

func getDb() *gorm.DB {

	config := OrmConfig{
		DbIp:           "127.0.0.1",
		DbPort:         3306,
		Dbname:         "godbc",
		Username:       "root",
		Password:       "fan1988",
		MaxIdleConns:   10,
		MaxOpenConns:   100,
		ConnectTimeout: 10,
		ShowSql:        true,
	}

	return initGorm(config)

}

func createReturnId(db *gorm.DB) interface{} {
	u := SysAccount{
		UserName:   "taotao",
		Password:   "532542523",
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}

	//增删查改
	result := db.Create(&u)
	fmt.Println("------------", result.RowsAffected, u.ID)

	//批量插入
	//var users = []User{u}
	//db.Create(&users)

	return u.ID
}

func getById(db *gorm.DB) interface{} {
	user := SysAccount{}
	var users []SysAccount

	//First、Last 方法会根据主键查找到第一个、最后一个记录， 它仅在通过 struct 或提供 model 值进行查询时才起作用。 如果 model 类型没有定义主键，则按第一个字段排序

	db.First(&user, 7)
	// SELECT * FROM users WHERE id = 10;

	// 获取第一条匹配的记录
	db.Model(&SysAccount{}).Where("id = ?", 7).First(&user)

	db.Where(&SysAccount{ID: 7}).First(&user)

	db.Raw("select * from sys_account where id = ?", 7).First(&user)

	fmt.Println(user)

	db.Find(&users, []int64{1, 7})
	// SELECT * FROM users WHERE id IN (1,2,3);
	db.Offset(0).Order("id ASC").Limit(2).Find(&users, []int64{1, 7})
	// SELECT * FROM users WHERE id IN (1,2,3) ORDER BY  id ASC LIMIT 0,2 ;

	db.Raw("select * from sys_account where id in (?)", []int64{1, 7}).Find(&users)

	fmt.Println(users)

	return user

}

func selectCount(db *gorm.DB) {
	var count int64
	db.Raw("select Count(*) from sys_account where id in (?)", []int64{1, 7}).Count(&count)
	fmt.Println("----------count:", count)
	db.Model(&SysAccount{}).Where("id = ?", 7).Count(&count)
	fmt.Println("----------count:", count)

	var sum int64
	row := db.Raw("select sum(id) from sys_account where id in (?)", []int64{1, 7}).Row()
	row.Scan(&sum)
	fmt.Println("----------sum:", sum)

}

func updateById(db *gorm.DB) {
	user := SysAccount{
		ID:         8,
		UserName:   "taotao333",
		Password:   "4444444",
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}
	//Save 会保存所有的字段，即使字段是零值
	//db.Save(&user)
	// 根据 `struct` 更新属性，只会更新非零值的字段
	affected := db.Model(&user).Updates(user).RowsAffected
	fmt.Println("-------------------------", affected)

	rowsAffected := db.Exec("UPDATE `sys_account` SET `user_name`=? WHERE `id` = ?", "taotao4444", 8).RowsAffected

	fmt.Println("-------------------------", rowsAffected)

}

func RowsScan(db *gorm.DB) []SysAccount {
	//rows, _ := db.Model(&SysAccount{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
	rows, _ := db.Raw("select * from sys_account where id in (?)", []int64{1, 7}).Rows() // (*sql.Rows, error)
	defer rows.Close()

	users := make([]SysAccount, 10)
	for rows.Next() {
		var user SysAccount
		// ScanRows 扫描一行到 user 模型
		db.ScanRows(rows, &user)
		users = append(users, user)

	}
	// do something

	return users
}

func delById(db *gorm.DB) {
	rowsAffected := db.Delete(&SysAccount{}, 10).RowsAffected
	// DELETE FROM users WHERE id = 10;
	fmt.Println("-------------------------", rowsAffected)

	db.Delete(&SysAccount{}, []int{2, 3})
	// DELETE FROM users WHERE id IN (1,2,3);

	// 带额外条件的删除
	affected := db.Where("user_name = ?", "taotao333").Delete(&SysAccount{}).RowsAffected
	fmt.Println("-------------------------", affected)
}

func runTx(db *gorm.DB) {

	//手动事务
	tx := db.Begin()
	//操作

	tx.Commit()

	//自动提交事务
	db.Transaction(func(tx *gorm.DB) error {
		// 在事务中执行一些 db 操作（从这里开始，您应该使用 'tx' 而不是 'db'）
		if err := tx.Create(&SysAccount{UserName: "Giraffe"}).Error; err != nil {
			// 返回任何错误都会回滚事务
			return err
		}

		if err := tx.Create(&SysAccount{UserName: "Lion"}).Error; err != nil {
			return err
		}

		// 返回 nil 提交事务
		return nil
	})

}

// TODO
func queryPage() {

}

func RunGorm() {
	db := getDb().Session(&gorm.Session{
		PrepareStmt: true,
	})

	//id := createReturnId(db)
	//fmt.Println(id)

	//GetById(db)

	//UpdateById(db)
	//DelById(db)

	selectCount(db)
}
